package com.sec.android.app.myfiles.util;

import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AbsListView;
//import android.widget.ExpandableListView;
import android.widget.ExpandableListView;

import com.sec.android.app.myfiles.fragment.AbsMyFilesFragment;
import com.sec.android.app.myfiles.fragment.filelist.FileListActionMenu;
import com.sec.android.app.myfiles.fragment.filelist.FileListAdapter;
import com.sec.android.app.myfiles.fragment.optimizestorage.OptimizeStorageFileListFragment;
import com.sec.android.app.myfiles.info.MediaFile;
import com.sec.android.app.myfiles.module.abstraction.AbsFileListAdapterImp;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.module.search.SearchFragment;
import com.sec.android.app.myfiles.navigation.NavigationInfo;
import com.sec.android.app.myfiles.navigation.NavigationManager;

import java.io.File;
import java.util.Map;

public class BixbyUtil {

    private static final String KEY_NESTING_CALLER = "bixby_caller";
    private static final String BIXBY_MYFILES_APP_NAME = "My Files";
    private static final String PATH = "_data";
    private static final String NAME = "name";
    private static final String EXT = "ext";
    private static final String FILE_TYPE = "file_type";
    private static final String SIZE = "size";
    private static final String DATE = "date";
    private static final String RECENT_DATE = "recent_date";
    private static final String IS_360 = "is_360_contents";
    private static final Uri MYFILE_CONTENT_URI = Uri.parse("content://myfiles/recent_files");


    public static AbsMyFilesFragment getCurFragment(int processId) {
        AbsMyFilesFragment curFragment = null;
        NavigationManager navigationMgr = NavigationManager.getInstance(processId);
        NavigationInfo curInfo = navigationMgr.getCurInfo();
        if (curInfo != null) {
            curFragment = curInfo.getCurFragment();
        }
        return curFragment;
    }

    public static FileRecord getFileRecord(int processId) {
        FileRecord record = null;
        NavigationManager navigationMgr = NavigationManager.getInstance(processId);
        NavigationInfo curInfo = navigationMgr.getCurInfo();
        if (curInfo != null) {
            record = curInfo.getCurRecord();
        }
        return record;
    }

    public static FileRecord getFileRecord(AbsMyFilesFragment curFragment) {
        return getFileRecord(curFragment, 1);
    }

    public static FileRecord getFileRecord(AbsMyFilesFragment curFragment, int ordinal) {
        FileRecord record = null;

        if (curFragment != null) {
            record = curFragment.getFileRecord(getFilePosition(curFragment, ordinal));
        }

        return record;
    }

    public static int getFilePosition(AbsMyFilesFragment curFragment, int ordinal) {
        int position = 0;

        if (curFragment != null) {
            AbsListView listView = curFragment.getListView();
            if (listView != null) {
                if (ordinal == -1) { // Last item
                    position = listView.getLastVisiblePosition();
                } else if (curFragment instanceof SearchFragment) { // N items
                    position = listView.getFirstVisiblePosition() + getOrdinalPosition(listView, ordinal);
                } else if (curFragment instanceof OptimizeStorageFileListFragment) {
                    position = getOrdinalPositionInGroupList(listView,
                            ((OptimizeStorageFileListFragment) curFragment).getAdapter(), ordinal);
                } else {
                    position = listView.getFirstVisiblePosition() + ordinal - 1;
                }
            }
        }

        return position;
    }

    private static int getOrdinalPositionInGroupList(AbsListView listView, FileListAdapter adapter, int ordinal) {
        int position = 1; // default value for exception handling
        if (adapter != null) {
            AbsFileListAdapterImp adapterImp = adapter.getAdapterImp();
            int[] groupInfo = adapterImp.getGroupInfo();
            int first = listView.getFirstVisiblePosition();
            int itemIndex = first;
            int ordinalIndex = ordinal;
            int passedGroupHeaderDuringOrdinalCounting = 0;
            boolean firstVisibleIsGroupHeader = (first == 0);
            for (int i = 0; i < groupInfo.length; i++) {
                if (itemIndex >= groupInfo[i]) {
                    itemIndex = itemIndex - groupInfo[i] - 1/*group header*/;
                    if (itemIndex < 0) {
                        firstVisibleIsGroupHeader = true;
                        itemIndex = 0;
                    }
                } else {
                    if (itemIndex + ordinalIndex <= groupInfo[i]) {
                        position = first + ordinal + passedGroupHeaderDuringOrdinalCounting;
                        if (!firstVisibleIsGroupHeader) {
                            position--;
                        }
                    } else {
                        // just remove item count. because ordinal not contains group header.
                        ordinalIndex -= groupInfo[i];
                        passedGroupHeaderDuringOrdinalCounting++;
                    }
                }
            }
        }
        return position;
    }

    private static int getOrdinalPosition(AbsListView listView, int ordinal) {
        int oPosition = 0;
        int childCount = 0;

        if (listView instanceof ExpandableListView) {
            int childCnt = listView.getChildCount();
            if (childCnt <= ordinal) {
                oPosition = ordinal;
            } else {
                for (int i = 0; i < childCnt; i++) {
                    long packedPosition = ((ExpandableListView) listView).getExpandableListPosition(i);
                    int itemType = ExpandableListView.getPackedPositionType(packedPosition);
                    if (itemType == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
                        childCount++;
                        oPosition = i;
                        if (childCount == ordinal) {
                            break;
                        }
                    }
                }
            }
        }

        return oPosition;
    }

    public static int getTotalCount(int processId) {
        int cnt = 0;
        AbsMyFilesFragment curFragment = getCurFragment(processId);
        if (curFragment != null) {
            cnt = curFragment.getTotalFileCount();
        }
        return cnt;
    }

    public static AbsListView getListView(int processId) {
        AbsListView listViewImp = null;
        AbsMyFilesFragment curFragment = getCurFragment(processId);
        if (curFragment != null) {
            listViewImp = curFragment.getListView();
        }
        return listViewImp;
    }

    public static void enter(int processId, FileRecord record) {
        if (record != null) {
            NavigationManager navigationMgr = NavigationManager.getInstance(processId);
            NavigationInfo curInfo = navigationMgr.getCurInfo();
            if (curInfo != null) {
                NavigationInfo navigationInfo = NavigationInfo.getInstance(curInfo, record);
                if (navigationInfo != null) {
                    curInfo.setFocusRecord(record);
                    navigationMgr.enter(navigationInfo);
                }
            }
        }
    }

    public static boolean getMenuItemVisibility(int processId, int resMenuId) {
        boolean isVisible = false;
        AbsMyFilesFragment curFragment = getCurFragment(processId);
        if (curFragment != null) {
            FileListActionMenu actionMenu = curFragment.getActionMenu();
            if (actionMenu != null) {
                Menu menu = actionMenu.getMenuInstance();
                if (menu != null) {
                    MenuItem menuItem = menu.findItem(resMenuId);
                    isVisible = menuItem != null && menuItem.isVisible();
                }
            }
        }
        return isVisible;
    }

    public static void setNestingCallerAppName(Intent intent) {
        if (intent != null) {
            intent.putExtra(KEY_NESTING_CALLER, BIXBY_MYFILES_APP_NAME);
        }
    }

    public static int getRecentItemCount(Context context) {
        int cnt = 0;
        try (Cursor cursor = context.getContentResolver().query(MYFILE_CONTENT_URI, new String[]{"_id"}, null, null, null)) {
            if (cursor != null && cursor.getCount() > 0) {
                cnt = cursor.getCount();
            }
        }
        return cnt;
    }

    public static void sendResponse(Context context, FileRecord record, boolean loadingStatus) {
        FileRecord.StorageType storageType = record.getStorageType();
    }

    public static void setUpRecentFiles(Context context, Map<String, String> map) {
        String path = map.get("Key2");
        String name = map.get("Key3");
        String fullpath = path + "/" + name;
        boolean ret = false;

        String selection = PATH + "=?" + " AND " + NAME + "=?";
        String[] selectionArgs = new String[]{
                path, name + ""};
        try (Cursor cursor = context.getContentResolver().query(MYFILE_CONTENT_URI, new String[]{"_id"}, selection, selectionArgs, null)) {
            if (cursor != null) {
                ret = cursor.getCount() != 0;
            }
        }
        if (!ret) {
            ContentValues values = new ContentValues(8);
            File file = SemFwWrapper.file(fullpath);
            long size = file.length();
            long date = file.lastModified();
            int fileType = MediaFile.getFileType(fullpath);
            String ext = MediaFile.getExtensionAsUpperCase(fullpath);

            values.put(PATH, path);
            values.put(NAME, name);
            values.put(EXT, ext);
            values.put(FILE_TYPE, fileType);
            values.put(SIZE, size);
            values.put(DATE, date);
            values.put(RECENT_DATE, System.currentTimeMillis());
            values.put(IS_360, false);
            try {
                context.getContentResolver().insert(MYFILE_CONTENT_URI, values);
            } catch (Exception e) {
            }
        }
    }
}
